#include "SpriteBatch.h"
#include "Node2D.h"

SpriteBatch::SpriteBatch(RenderContext* context)
:pContext(context)
{
}
SpriteBatch::~SpriteBatch(void)
{
}
void SpriteBatch::begin()
{
	if (pContext == NULL || pContext->getEffect() == NULL)
	{
		return;
	}
	Technique* pEffect = pContext->getEffect();
	pEffect->enable();
	glEnable (GL_TEXTURE_2D);
	glEnable(GL_BLEND);        
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void SpriteBatch::end()
{
}
void SpriteBatch::dispose()
{

}
void SpriteBatch::draw(V3F_C4B_T2F_Quad mQuad)
{
	if (pContext == NULL || pContext->getEffect() == NULL)
	{
		return;
	}
	Technique* pEffect = pContext->getEffect();
	float w = pContext->getStageSize().width;
	float h = pContext->getStageSize().height;
	if (w < 0.0f || h < 0.0f)
	{
		return;
	}
	glViewport(0, 0, w, h);

	GLuint mWVPLoc = pEffect->getUniformLocation("gWVP");
	GLuint mWorldMatrixLoc = pEffect->getUniformLocation("gWorld");
	V3F_C4B_T2F_Quad* quad = &mQuad;
	long offset = (long)quad;
	// vertex
	int diff = offsetof( V3F_C4B_T2F, vertices);
	glVertexAttribPointer(pEffect->getAttribLocation("a_position"), 3, GL_FLOAT, GL_FALSE, sizeof(quad->lb), (void*) (offset + diff));

	// texCoods
	diff = offsetof( V3F_C4B_T2F, texCoords);
	glVertexAttribPointer(pEffect->getAttribLocation("a_texCoord"), 2, GL_FLOAT, GL_FALSE, sizeof(quad->lb), (void*)(offset + diff));

	// color
	diff = offsetof( V3F_C4B_T2F, colors);
	glVertexAttribPointer(pEffect->getAttribLocation("a_color"), 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(quad->lb), (void*)(offset + diff));

	glEnableVertexAttribArray ( pEffect->getAttribLocation("a_position") );
	glEnableVertexAttribArray ( pEffect->getAttribLocation("a_texCoord") );
	glEnableVertexAttribArray ( pEffect->getAttribLocation("a_color") );

	unsigned int texid = mQuad.tex;
	if (texid!= 0)
	{
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texid);
		// Set the base map sampler to texture unit to 0
		glUniform1i ( pEffect->getUniformLocation("s_baseMap"), 0 );
	}
	glUniform4f( pEffect->getUniformLocation("a_viewport"),0,  w, h, 0 );

	//glUniform4f( pEffect->getUniformLocation("a_viewport"),(float)-1.0 / widthRatio,  (float)1.0 / widthRatio,(float)-1.0 / heightRatio, (float)1.0 / heightRatio );
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void SpriteBatch::draw(Texture* texture,Rect destinationRectangle,Color4B color)
{
	draw(texture,destinationRectangle,SizeOne,color,0);
}
void SpriteBatch::draw(Texture* texture,Point position,Color4B color)
{
	Rect destinationRectangle(position.x,position.y,texture->getSize().width,texture->getSize().height);
	draw(texture,destinationRectangle,SizeOne,color,0);
}
void SpriteBatch::draw(Texture* texture,Rect destinationRectangle,Size texCoord,Color4B color)
{
	draw(texture,destinationRectangle,texCoord,color,0);
}
void SpriteBatch::draw(Texture* texture,Point position,Size texCoord,Color4B color)
{
	Rect destinationRectangle(position.x,position.y,texture->getSize().width,texture->getSize().height);
	draw(texture,destinationRectangle,texCoord,color,0);
}
//all in one
void SpriteBatch::draw(Texture* texture,Rect destinationRectangle,Size texCoord,Color4B color,float rotation,Point origin,Point scale,SpriteEffects effects)
{
	Node2D transformNode;
	transformNode.ignoreAnchorPointForPosition(true);
	transformNode.setPosition(destinationRectangle.origin);
	transformNode.setContentSize(destinationRectangle.size);
	transformNode.setTexCoord(texCoord);
	transformNode.setColor(color);
	transformNode.setRotation(rotation);
	transformNode.setAnchorPoint(origin);
	transformNode.setScaleX(scale.x);
	transformNode.setScaleY(scale.y);
	transformNode.update();
	V3F_C4B_T2F_Quad quad = transformNode.getRenderQuad();
	if (texture != NULL)
	{
		quad.tex = texture->getTexID();
	}

	draw(quad);
}
void SpriteBatch::draw(Texture* texture,Point position,Size texCoord,Color4B color,float rotation,Point origin,Point scale,SpriteEffects effects)
{
	Rect destinationRectangle(position.x,position.y,texture->getSize().width,texture->getSize().height);
	draw(texture,destinationRectangle,texCoord,color,rotation,origin,scale,effects);
}
void SpriteBatch::drawString(wchar_t* _strText,int x , int y, int maxW , int h,Color4B color)
{
	if (pContext == NULL || pContext->getEffect() == NULL)
	{
		return;
	}
	Technique* pEffect = pContext->getEffect();
	pEffect->disable();
	glColor3ub(color.r,color.g,color.b);
	FreeTypeFontSingleton::getSingleton()->drawText(_strText, x, y, maxW,h);
	pEffect->enable();
}
void SpriteBatch::drawString(FreeTypeFont* font,std::string text, Point position,Color4B color)
{

}
void SpriteBatch::drawString(FreeTypeFont* font,std::string text, Point position,Color4B color,float rotation,Point origin,Point scale)
{

}
